import 'package:flutter/cupertino.dart';
import 'package:kmxy_base/base/base_package.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

typedef Cell1WidgetCallback = Widget Function(String? titleData);
typedef TitleWidgetCallback = Widget Function(String? titleData, int index);
typedef Cell1ContentWidgetCallback = Widget Function(
    String? contentData, int index, Map itemData);
typedef ContentWidgetCallback = Widget Function(
    String? contentData, int index, String key, Map itemData);
typedef ItemClickCallback = void Function(Map itemData, int index);
typedef TableListViewCreatedCallback = void Function(
    TableListViewController controller);

class TitleData {
  String data = '';
  double width = 0;
  String contentKey = "";

  TitleData(this.data, this.width, this.contentKey);
}

class TableListView extends StatefulWidget {
  // 标题
  final List<TitleData> titleList;
  // 数据
  final List dataList;
  // 标题的高度
  final double titleHeight;
  // 标题上第一个单元格的宽度
  // 内容的高度
  final double contentHeight;
  // 是否开启下拉加载更多
  final bool enablePullDown;
  // 是否开启上拉刷新
  final bool enablePullUp;
  // 没有数据的view
  final Widget? noDataView;
  // 边框宽度
  final double borderWidth;
  // 边框颜色
  final Color borderColor;
  // 标题背景颜色
  final Color titleBgColor;
  // 内容背景颜色
  final Color contentBgColor;
  // 第一个单元格标题回调
  final Cell1WidgetCallback cell1WidgetCallback;
  // 标题回调
  final TitleWidgetCallback titleWidgetCallback;
  // 第一个单元格内容回调
  final Cell1ContentWidgetCallback cell1ContentWidgetCallback;
  // 内容回调
  final ContentWidgetCallback contentWidgetCallback;
  // 条目点击回调
  final ItemClickCallback? itemClickCallback;
  // 数据更新控制器回调
  final TableListViewCreatedCallback onTableListViewCreated;
  final OnRefresh? onRefresh;
  final OnLoading? onLoading;
  // 是否是竖屏
  final bool isVertical;
  // 宽度差值，横屏是用到
  final double widthGap;

  const TableListView({
    required this.onTableListViewCreated,
    required this.titleList,
    required this.dataList,
    required this.titleHeight,
    required this.contentHeight,
    required this.cell1WidgetCallback,
    required this.titleWidgetCallback,
    required this.cell1ContentWidgetCallback,
    required this.contentWidgetCallback,
    this.enablePullDown = true,
    this.enablePullUp = true,
    this.noDataView,
    this.borderWidth = 0,
    this.borderColor = Colors.grey,
    this.titleBgColor = Colors.white,
    this.contentBgColor = Colors.white,
    this.onRefresh,
    this.onLoading,
    this.itemClickCallback,
    this.isVertical = true,
    this.widthGap = 0,
    Key? key,
  }) : super(key: key);

  @override
  _TableListViewState createState() => _TableListViewState();
}

class _TableListViewState extends State<TableListView> {
  ScrollController titleControllerH = ScrollController();
  ScrollController leftController = ScrollController();
  ScrollController contentController = ScrollController();
  ScrollController contentControllerH = ScrollController();

  RefreshController refreshController = RefreshController();

  bool titleIsPan = false;
  bool leftIsPan = false;
  bool contentIsPan = false;
  bool isLoading = false;

  titlePanDown(DragDownDetails? onPanDown) {
    titleIsPan = true;
    leftIsPan = false;
    contentIsPan = false;
  }

  leftPanDown(DragDownDetails? onPanDown) {
    leftIsPan = true;
    titleIsPan = false;
    contentIsPan = false;
  }

  contentPanDown(DragDownDetails? onPanDown) {
    contentIsPan = true;
    titleIsPan = false;
    leftIsPan = false;
  }

  @override
  void initState() {
    super.initState();
    leftController.addListener(() {
      if (leftIsPan) {
        contentController.position.moveTo(leftController.offset);
      }
    });
    titleControllerH.addListener(() {
      if (titleIsPan) {
        contentControllerH.position.moveTo(titleControllerH.offset);
      }
    });

    contentController.addListener(() {
      if (contentIsPan) {
        leftController.position.moveTo(contentController.offset);
      }
    });
    contentControllerH.addListener(() {
      if (contentIsPan) {
        titleControllerH.position.moveTo(contentControllerH.offset);
      }
    });
    WidgetsBinding.instance?.addPostFrameCallback((mag) {
      widget.onTableListViewCreated(
          TableListViewController(refreshController, this));
    });
  }

  @override
  void dispose() {
    refreshController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Column(
        children: [
          SizedBox(
            height: widget.titleHeight,
            child: Row(
              children: [
                Container(
                  width:
                      widget.titleList.isEmpty ? 0 : widget.titleList[0].width,
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: widget.titleBgColor,
                    border: Border(
                      left: BorderSide(
                          width: widget.borderWidth, color: widget.borderColor),
                      right: BorderSide(
                          width: widget.borderWidth / 2,
                          color: widget.borderColor),
                      top: BorderSide(
                          width: widget.borderWidth, color: widget.borderColor),
                      bottom: BorderSide(
                          width: widget.borderWidth, color: widget.borderColor),
                    ),
                  ),
                  child: widget.cell1WidgetCallback(widget.titleList.isEmpty
                      ? ''
                      // ignore: unnecessary_type_check
                      : (widget.titleList[0].data is String ||
                              // ignore: unnecessary_null_comparison
                              widget.titleList[0].data == null)
                          ? widget.titleList[0].data
                          : widget.titleList[0].data.toString()),
                ),
                GestureDetector(
                  onPanDown: titlePanDown,
                  child: SizedBox(
                    width: ( MediaQuery.of(context).size.width -
                                widget.widthGap) -
                        (widget.titleList.isEmpty
                            ? 0
                            : widget.titleList[0].width),
                    child: SingleChildScrollView(
                      controller: titleControllerH,
                      scrollDirection: Axis.horizontal,
                      child: Row(
                        children: List.generate(
                          widget.titleList.length - 1,
                          (index) => Container(
                            width: widget.titleList[index + 1].width,
                            height: widget.titleHeight,
                            alignment: Alignment.center,
                            decoration: BoxDecoration(
                              color: widget.titleBgColor,
                              border: Border(
                                left: BorderSide(
                                    width: widget.borderWidth / 2,
                                    color: widget.borderColor),
                                right: BorderSide(
                                    width:
                                        index == (widget.titleList.length - 2)
                                            ? widget.borderWidth
                                            : widget.borderWidth / 2,
                                    color: widget.borderColor),
                                top: BorderSide(
                                    width: widget.borderWidth,
                                    color: widget.borderColor),
                                bottom: BorderSide(
                                    width: widget.borderWidth,
                                    color: widget.borderColor),
                              ),
                            ),
                            child: widget.titleWidgetCallback(
                                // ignore: unnecessary_type_check
                                (widget.titleList[index + 1].data is String ||
                                        // ignore: unnecessary_null_comparison
                                        widget.titleList[index + 1].data ==
                                            null)
                                    ? widget.titleList[index + 1].data
                                    : widget.titleList[index + 1].data
                                        .toString(),
                                index + 1),
                          ),
                        ),
                      ),
                    ),
                  ),
                )
              ],
            ),
          ),
          Expanded(
            child: SmartRefresher(
              enablePullDown: widget.enablePullDown,
              enablePullUp: widget.enablePullUp,
              header: const WaterDropHeader(
                complete: Text("数据刷新"),
                failed: Text("没有数据了"),
              ),
              footer: CustomFooter(
                builder: (BuildContext context, LoadStatus? mode) {
                  Widget body;
                  if (mode == LoadStatus.idle) {
                    body = const Text("上拉加载");
                  } else if (mode == LoadStatus.loading) {
                    body = const CupertinoActivityIndicator();
                  } else if (mode == LoadStatus.failed) {
                    body = const Text("加载失败,点击重试");
                  } else if (mode == LoadStatus.canLoading) {
                    body = const Text("松手,加载更多");
                  } else {
                    body = const Text("没有更多数据了");
                  }
                  return SizedBox(
                    height: 55,
                    child: Center(child: body),
                  );
                },
              ),
              controller: refreshController,
              onRefresh: widget.onRefresh,
              onLoading: widget.onLoading,
              child: widget.dataList.isEmpty
                  ? (widget.noDataView ??
                      Container(
                        alignment: Alignment.center,
                        child: Text(isLoading ? '加载中...' : '没有数据'),
                      ))
                  : Row(
                      children: [
                        GestureDetector(
                          onPanDown: leftPanDown,
                          child: SingleChildScrollView(
                            controller: leftController,
                            child: Column(
                              children: List.generate(
                                widget.dataList.length,
                                (index) => InkWell(
                                  onTap: () {
                                    if (widget.itemClickCallback != null) {
                                      widget.itemClickCallback!(
                                          widget.dataList[index], index);
                                    }
                                  },
                                  child: Container(
                                    width: widget.titleList.isEmpty
                                        ? 0
                                        : widget.titleList[0].width,
                                    height: widget.contentHeight,
                                    alignment: Alignment.center,
                                    decoration: BoxDecoration(
                                      color: widget.contentBgColor,
                                      border: Border(
                                        left: BorderSide(
                                            width: widget.borderWidth,
                                            color: widget.borderColor),
                                        right: BorderSide(
                                            width: widget.borderWidth / 2,
                                            color: widget.borderColor),
                                        top: BorderSide(
                                            width: 0,
                                            color: widget.borderColor),
                                        bottom: BorderSide(
                                            width: widget.borderWidth,
                                            color: widget.borderColor),
                                      ),
                                    ),
                                    child: widget.cell1ContentWidgetCallback(
                                        (widget.dataList[index][widget
                                                    .titleList[0]
                                                    .contentKey] is String ||
                                                widget.dataList[index][widget
                                                        .titleList[0]
                                                        .contentKey] ==
                                                    null)
                                            ? widget.dataList[index]
                                                [widget.titleList[0].contentKey]
                                            : widget.dataList[index]
                                                    [widget.titleList[0].contentKey]
                                                .toString(),
                                        index,
                                        widget.dataList[index]),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ),
                        SizedBox(
                          width: (MediaQuery.of(context).size.width -
                                      widget.widthGap) -
                              (widget.titleList.isEmpty
                                  ? 0
                                  : widget.titleList[0].width),
                          child: GestureDetector(
                            onPanDown: contentPanDown,
                            child: SingleChildScrollView(
                              controller: contentController,
                              child: SingleChildScrollView(
                                controller: contentControllerH,
                                scrollDirection: Axis.horizontal,
                                child: Column(
                                  children: List.generate(
                                    widget.dataList.length,
                                    (index) => InkWell(
                                      onTap: () {
                                        if (widget.itemClickCallback != null) {
                                          widget.itemClickCallback!(
                                              widget.dataList[index], index);
                                        }
                                      },
                                      child: Row(
                                        children: List.generate(
                                          widget.titleList.length - 1,
                                          (indexN) => Container(
                                            width: widget
                                                .titleList[indexN + 1].width,
                                            height: widget.contentHeight,
                                            alignment: Alignment.center,
                                            decoration: BoxDecoration(
                                              color: widget.contentBgColor,
                                              border: Border(
                                                left: BorderSide(
                                                    width: widget.borderWidth,
                                                    color: widget.borderColor),
                                                right: BorderSide(
                                                    width: index ==
                                                            (widget.titleList
                                                                    .length -
                                                                2)
                                                        ? widget.borderWidth
                                                        : widget.borderWidth /
                                                            2,
                                                    color: widget.borderColor),
                                                top: BorderSide(
                                                    width: 0,
                                                    color: widget.borderColor),
                                                bottom: BorderSide(
                                                    width: widget.borderWidth,
                                                    color: widget.borderColor),
                                              ),
                                            ),
                                            child: widget.contentWidgetCallback(
                                                (widget.dataList[index]
                                                                [widget.titleList[indexN + 1].contentKey]
                                                            is String ||
                                                        widget.dataList[index][widget.titleList[indexN + 1].contentKey] ==
                                                            null)
                                                    ? widget.dataList[index][widget
                                                        .titleList[indexN + 1]
                                                        .contentKey]
                                                    : widget
                                                        .dataList[index][widget
                                                            .titleList[indexN + 1]
                                                            .contentKey]
                                                        .toString(),
                                                indexN,
                                                widget.titleList[indexN + 1].contentKey,
                                                widget.dataList[index]),
                                          ),
                                        ),
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
            ),
          ),
        ],
      ),
    );
  }

  setIsLoading(bool loadingState) {
    setState(() {
      isLoading = loadingState;
    });
  }
}

class TableListViewController {
  late RefreshController refreshController;
  late _TableListViewState viewState;

  TableListViewController(
      RefreshController controller, _TableListViewState state) {
    refreshController = controller;
    viewState = state;
    viewState.setIsLoading(true);
  }

  /// true 没有更多数据
  void onFinishLoading(bool isNoData) {
    if (isNoData) {
      refreshController.loadNoData();
    } else {
      refreshController.loadComplete();
    }
    viewState.setIsLoading(false);
  }

  onFinishRefresh() {
    refreshController.loadComplete();
    refreshController.refreshCompleted();
    viewState.setIsLoading(false);
  }

  setIsLoading(bool loadingState) {
    viewState.setIsLoading(loadingState);
  }
}
